#include "data_segment.h"
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <string>

namespace safe_udp
{
    DataSegment::DataSegment()
    {
        ack_number_ = -1;
        seq_number_ = -1;
        length_ = -1;
    };
    // 序列化
    char *DataSegment::SerializeToCharArray()
    {
        // 接收报文正文数据的指针还残有正文数据
        if (final_packet_ != nullptr)
        {
            // 将指针内容都设置为0，长度是1472字节
            memset(final_packet_, 0, MAX_PACKET_SIZE);
        }
        else // 为空
        {
            final_packet_ = reinterpret_cast<char *>(calloc(MAX_PACKET_SIZE, sizeof(char)));

            if (final_packet_ == nullptr)
            {
                return nullptr;
            }
        }
        // 复制seq_number内容到报文的前32位（4字节），seq_number为序号
        memcpy(final_packet_, &seq_number_, sizeof(seq_number_));

        // 指针向后移动4字节，新的4字节存储确认序号
        memcpy((final_packet_ + 4), &ack_number_, sizeof(ack_number_));

        // 拼接1字节的ack标志位
        memcpy((final_packet_ + 8), &ack_flag_, 1);

        // 拼接1字节的fin标志位
        memcpy((final_packet_ + 9), &fin_flag_, 1);

        // 拼接数据长度字段
        memcpy((final_packet_ + 10), &length_, sizeof(length_));

        // 拼接有效载荷
        memcpy((final_packet_ + 12), &data_, length_);

        return final_packet_;
    };

        // 反序列化到数据段
    void DataSegment::DeserializeToDataSegment(unsigned char *data_segment,
                                               int length)
    {
        //小端字节序转为网络字节序（大端）
        seq_number_ = convert_to_uint32(data_segment, 0);
        ack_number_ = convert_to_uint32(data_segment, 4);
        ack_flag_ = convert_to_bool(data_segment, 8);
        fin_flag_ = convert_to_bool(data_segment, 9);
        length_ = convert_to_uint16(data_segment, 10);

        // 为正文data开辟空间
        data_ = reinterpret_cast<char *>(calloc(length + 1, sizeof(char)));

        //char*地址+12，向后偏移12个字节的内容就是正文
        //复制 （目的）正文 （源头）报文+safe_udp报头
        memcpy(data_, data_segment + HEADER_LENGTH, length);
        *(data_ + length) = '\0';
    }

    uint32_t DataSegment::convert_to_uint32(unsigned char *buffer,
                                            int start_index)
    {
        // 将4个字节每个字节的内容进行转换字节序
        uint32_t uint32_value = (buffer[start_index + 3] << 24) | (buffer[start_index + 2] << 16) |
                                (buffer[start_index + 1] << 8) | (buffer[start_index]);
        return uint32_value;
    }

    uint16_t DataSegment::convert_to_uint16(unsigned char *buffer,
                                            int start_index)
    {
        // 转换字节序
        uint16_t uint16_value = (buffer[start_index + 1] << 8) | (buffer[start_index]);
        return uint16_value;
    }

    bool DataSegment::convert_to_bool(unsigned char *buffer, int index)
    {
        bool bool_value = buffer[index];//取报文的标志位 
        return bool_value;
    }
}